package cn.pugle.json.jackson;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.io.IOException;

/**
 * 动态子类
 * @author tzp
 * @since 2018/9/12
 */
public class Zoo {
    public Animal animal;

    @Override
    public String toString() {
        return "Zoo{" +
                "animal=" + animal +
                '}';
    }

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            property = "type")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = Dog.class, name = "dog"),
            @JsonSubTypes.Type(value = Cat.class, name = "cat")
    })
    public static class Animal {
        public String name;
    }

    @JsonTypeName("dog")
    public static class Dog extends Animal {
        public double barkVolume;

        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", barkVolume=" + barkVolume +
                    '}';
        }
    }

    @JsonTypeName("cat")
    public static class Cat extends Animal {
        public int lives;
        boolean likesCream;

        @Override
        public String toString() {
            return "Cat{" +
                    "name='" + name + '\'' +
                    ", lives=" + lives +
                    ", likesCream=" + likesCream +
                    '}';
        }
    }

    @Test
    public void test()
            throws IOException {
        Zoo.Dog dog = new Zoo.Dog();
        dog.name = "lacy";
        Zoo zoo = new Zoo();
        zoo.animal = dog;

        ObjectMapper objectMapper = new ObjectMapper();
        String result = objectMapper
                .writeValueAsString(zoo);

        System.out.println(result);

        String json = "{\n" +
                "    \"animal\": {\n" +
                "        \"type\": \"dog\",\n" +
                "        \"name\": \"lacy\",\n" +
                "        \"barkVolume\": 0\n" +
                "    }\n" +
                "}";
        System.out.println(json);

        Zoo zoo1 = objectMapper.readValue(json, Zoo.class);
        System.out.println(zoo1);
        System.out.println(objectMapper.writeValueAsString(zoo1));
    }
}